#include"Decision.h"
#include<list>
#include<stack>
#include<map>
using namespace Dec;
using namespace std;
namespace ThreeRember
{

    map<size_t, size_t> ACT_COUNT;
    map<size_t, size_t> EMO_COUNT;

    template <class K, class T>
    class LRUCache {
    public:
        LRUCache(int capacity = 7)
            :_capacity(capacity)
        {
        }

        pair<bool,T> get(K key) {
            auto it = _hashmap.find(key);
            if (it == _hashmap.end())
            {
                return make_pair(false,T());
            }
            else
            {
                auto listit = it->second;
                //交换位置，将访问的向前放
                _list.splice(_list.begin(), _list, listit);
                return make_pair(true,_list.front());
            }
        }
        pair<K,T> get_first()
        {
            return _list.front();
        }
        void put(K key, T& value) {
            auto it = _hashmap.find(key);
            if (it == _hashmap.end())
            {
                if (_capacity <= _hashmap.size())
                {
                    //满了，需要删除
                    _hashmap.erase(_list.back().first);
                    _list.pop_back();
                }

                _list.push_front(make_pair(key, value));
                _hashmap[key] = _list.begin();

            }
            else {
                it->second->second = value;
                _list.splice(_list.begin(), _list, it->second);
              
            }
        }
        void clear()
        {
            _flag = -1;
            _list.clear();
            _hashmap.clear();
        }
        size_t& set_flag()
        {
            return _flag;
        }
        size_t count()
        {
            return _list.size();
        }

        list<pair<K, T>>& get_list()
        {
            return _list;
        }
        typedef typename std::list<pair<K, T>>::iterator LSite;
    private:
        //using LSite = std::list<pair<K,T>>::iterator;
        unordered_map<K, LSite> _hashmap;//查找哈希
        list<pair<K, T>> _list;//存储链表
        size_t _capacity;//容量
        size_t _flag = 255;//备注标记
    };

    struct RobotLastRember //第一层记忆存储信息结构
    {
        RobotLastRember(size_t act = ACTION_UNKNOW,size_t emo = EMO_UNKNOW,size_t bias = 0)
            :_act(act),_emo(emo),_bias(bias)
        {}
        size_t _act ;
        size_t _emo ;
        size_t _bias;
    };

    struct PeopleLastRember//第二层记忆存储信息结构
    {
        PeopleLastRember(size_t order_flag = STA_POSE,size_t order=ORDER_UNKNOW,size_t bias=0,size_t emo=EMO_UNKNOW,size_t act = ACTION_UNKNOW,size_t count=0,time_t time = 0)
            :_order_flag(order_flag),_order(order),_bias(bias),_emo(emo),_act(act),_count(count),_time(time)
        {}
        size_t _order_flag = STA_POSE;
        size_t _order = ORDER_UNKNOW;
        size_t _bias = 0;
        size_t _emo = EMO_UNKNOW;
        size_t _act = ACTION_UNKNOW;
        size_t _count = 0;
        time_t _time = 0;
    };

    struct HistoryRember//第三层记忆存储信息结构
    {
        size_t _name;
        size_t _many_emo = EMO_UNKNOW;
        size_t _many_act = ACTION_UNKNOW;
        int _bais = 0;
        unordered_map <size_t, size_t> _ordermap;//<<模式,指令>,次数>
        pair<size_t, size_t> _order;//指令  <模式,指令>
        unordered_map<size_t, size_t> _action_count;//动作执行次数
        unordered_map<size_t, size_t> _emotion_count;//表情执行次数
    };
    struct FirstFeature //第一层特征返回
    {
        FirstFeature(size_t b = 0,size_t act = 0,size_t emo =0)
            :bias(b),_many_reaction(act,emo)
        {}
        size_t bias;//整体偏向
        pair<size_t, size_t> _many_reaction; // 最多反应,动作，表情
    };
    struct SecondFeature//第二层特征返回
    {
        SecondFeature(size_t c=0,size_t t=0,size_t b=0,size_t m_a=0,size_t m_e=0,size_t o_a=0,size_t o_e=0)
            :_count(c),_time_span(t),bias(b),_many_reaction(m_a,m_e),_order_reaction(o_a,o_e)
        {}
        size_t _count = 0;//执行次数 0：少数 1：较多 2：多数 
        size_t _time_span = 0; //间隔时间 0：临近 1：短期 2：长期
        size_t bias;//整体偏向 1友好、2敌对
        pair<size_t, size_t> _many_reaction;// 最多反应，动作，表情
        pair<size_t, size_t> _order_reaction;//指令反应，

    };
    struct ThreeFeature//第三层特征返回
    {
        ThreeFeature(size_t b=0,size_t act=0,size_t emo=0)
            :bias(b),_order_reaction(act,emo)
        {}
        size_t bias;//整体偏向
        pair<size_t, size_t> _order_reaction;//指令反应，动作，表情
    };


    class ThreeRemberCache
    {
    public:
        ThreeRemberCache(int cap = 7)
            :_first_cache(cap)
            , _second_cache(cap)
        {
        }
        void First_Put(RobotLastRember& value)
        {
            _first_cache.put(keys, value);
            keys++;
        }
        void Second_Put(size_t name,  PeopleLastRember& value)
        {
            size_t _name = _second_cache.set_flag();
            if (_name == 255)
            {
                _second_cache.set_flag() = name;
                _name = name;
            }
            if (_name != name)//数据切换清除
            {
                if (_third_cache.find(_name) == _third_cache.end())//没找到
                {
                    _third_cache[_name] = HistoryRember();
                }
                //存储短期到长期
                auto name_it = _third_cache.find(_name);
                name_it->second._name = _name;
                int bias = 0;
                for (auto& it : _second_cache.get_list())
                {
                    size_t  flag = it.second._order_flag;
                    size_t tamp_order = it.second._order;
                    if (it.second._bias == 1)
                    {
                        bias++;
                    }
                    else
                        bias--;
                    if(flag == STA_VOICE)
                        tamp_order = tamp_order<< BIT_POS;
                    name_it->second._ordermap[tamp_order]++;
                    name_it->second._action_count[it.second._act]++;
                    name_it->second._emotion_count[it.second._emo]++;
                    
                }
                int max_count = name_it->second._ordermap.begin()->second;
                size_t max_order = name_it->second._ordermap.begin()->first;
                for (auto& it : name_it->second._ordermap)
                {
                    if (it.second > max_count)
                    {
                        max_count = it.second;
                        max_order = it.first;
                    }
                }
                if (max_order > BIT_MAX)
                {
                    name_it->second._order.first = STA_VOICE;
                    name_it->second._order.second = max_order >> BIT_POS;
                }
                else
                {
                    name_it->second._order.first = STA_POSE;
                    name_it->second._order.second = max_order;
                }
                
                name_it->second._bais += bias;

                int max_action_count = name_it->second._action_count.begin()->second;
                int max_action = name_it->second._action_count.begin()->first;
                for (auto& it : name_it->second._action_count)
                {
                    if (it.second > max_action_count)
                    {
                        max_action_count = it.second;
                        max_action = it.first;
                    }
                }
                int max_emotion_count = name_it->second._emotion_count.begin()->second;
                int max_emotion = name_it->second._emotion_count.begin()->first;
                for (auto& it : name_it->second._emotion_count)
                {
                    if (it.second > max_emotion_count)
                    {
                        max_emotion_count = it.second;
                        max_emotion = it.first;
                    }
                }

                name_it->second._many_act = max_action;
                name_it->second._many_emo = max_emotion;



                //保存
                stack<pair<size_t,PeopleLastRember>> st;
                for (auto it : _second_cache.get_list())
                {
                    st.push(make_pair(it.first,it.second));
                }
                _last_map[_name] = st;
                //切换
                auto tap = _last_map.find(name);//从切换队列中寻找
                if (tap == _last_map.end())//此人没有近期交互记录
                {
                    _second_cache = LRUCache<size_t, PeopleLastRember>();
                }
                else//有近期交互记录
                {
                    auto tst = tap->second;
                    while (!tst.empty())
                    {
                        _second_cache.put(tst.top().first, tst.top().second);
                        tst.pop();
                    }
                }
                _second_cache.set_flag() = name;
            }
            size_t order = value._order;
            if (value._order_flag == STA_VOICE)
                order = order << BIT_POS;
            _second_cache.put(order, value);
        }
        pair<bool, FirstFeature> First_feature()
        {

            if (_first_cache.count() > 3)//满足特征获取条件
            {
                auto list = _first_cache.get_list();
                int bias = 0;
                for (auto& it : list)
                {
                    if (it.second._bias == 1)
                    {
                        bias++;
                    }
                    else
                        bias--;
                    ACT_COUNT[it.second._act]++;
                    EMO_COUNT[it.second._emo]++;
                }
                size_t act = 0;
                size_t actcount = 0;
                size_t emo = 0;
                size_t emocount = 0;
                for (auto& it : ACT_COUNT)
                {
                    if (it.second > actcount)
                    {
                        act = it.first;
                        actcount = it.second;
                    }
                }
                for (auto& it : EMO_COUNT)
                {
                    if (it.second > emocount)
                    {
                        emo = it.first;
                        emocount = it.second;
                    }
                }
                ACT_COUNT.clear();
                EMO_COUNT.clear();
                if (actcount == 1) act = _first_cache.get_first().second._act;
                if (emocount == 1) emo = _first_cache.get_first().second._emo;

                return make_pair(true, FirstFeature(bias > 0 ? 1 : 2, act, emo));

            }
            else
                return make_pair(false, FirstFeature());
        }
        pair<bool, SecondFeature> Second_feature(size_t flag, size_t order)
        {
            if (_second_cache.count() > 3)
            {
                auto list = _second_cache.get_list();
                int bias = 0;
                bool f = true;
                PeopleLastRember lastR;
                for (auto& it : list)
                {
                    if (f && it.second._order_flag == flag && order == it.second._order)
                    {
                        f = false;
                        lastR = it.second;
                    }
                    if (it.second._bias == 1)
                    {
                        bias++;
                    }
                    else
                        bias--;
                    ACT_COUNT[it.second._act]++;
                    EMO_COUNT[it.second._emo]++;
                }
                if (f == true)//近期没有执行过
                    lastR = _second_cache.get_first().second;
                size_t act = 0;
                size_t actcount = 0;
                size_t emo = 0;
                size_t emocount = 0;
                for (auto& it : ACT_COUNT)
                {
                    if (it.second > actcount)
                    {
                        act = it.first;
                        actcount = it.second;
                    }
                }
                for (auto& it : EMO_COUNT)
                {
                    if (it.second > emocount)
                    {
                        emo = it.first;
                        emocount = it.second;
                    }
                }
                ACT_COUNT.clear();
                EMO_COUNT.clear();
                if (actcount == 1) act = _first_cache.get_first().second._act;
                if (emocount == 1) emo = _first_cache.get_first().second._emo;
                time_t now_time = time(NULL);
                time_t time = now_time - lastR._time;
                size_t time_span = 0;
                size_t count = 0;

                if (time > 120)
                    time_span = 2;
                else if (time > 20)
                    time_span = 1; 

                if (lastR._count > 50)
                    count = 2;
                else if (lastR._count > 20)
                    count = 1;

                return make_pair(true, SecondFeature(count, time_span, bias > 0 ? 1 : 2, act, emo, lastR._act, lastR._emo));
            }
            else
                return make_pair(false, SecondFeature());
        }
        pair<bool,ThreeFeature> Three_feature(size_t name)
        {
            if (_third_cache.find(name) == _third_cache.end())
                return make_pair(false, ThreeFeature());
            int tm_bais = _third_cache.find(name)->second._bais;
            size_t bais = 0;
            if (tm_bais >= 0)
            {
                bais = 1;
            }
            else
                bais = 2;
            size_t m_act = _third_cache.find(name)->second._many_act;
            size_t m_emo = _third_cache.find(name)->second._many_emo;
            return make_pair(true, ThreeFeature(bais, m_act, m_emo));
        }

    private:
        LRUCache<size_t, RobotLastRember> _first_cache;
        LRUCache<size_t, PeopleLastRember> _second_cache;
        unordered_map<size_t, HistoryRember> _third_cache;
        unordered_map<size_t, stack<pair<size_t, PeopleLastRember>>> _last_map;
        size_t keys = 0;
    };
}